package models;

import java.util.*;

import javax.persistence.*;

import controllers.Users;

import play.db.jpa.*;

/**
 * 
 * @author abdalla abd-alhady
 * @version 1.0
 * 
 */
@Entity
public class Notification extends Model {
	@Lob
	public String description;
	@ManyToMany
	public List<User> notified;
	public long objectID;
	/**
	 * 0 = ActionItem 1 = ActionLog 2 = Comment 3 = Entity 4 = Idea 5 =
	 * IdeaRating 6 = Organization 7 = permission 8 = Plan 9 = Role 10 = Tag 11
	 * = topic 12 = User 13 = Merge Request 14=Invitation 15 = Sharing
	 * 16=deleting a topic 17= hide idea 18=Topic Request
	 */
	public int objectType;
	@ManyToOne
	public User notifictionTrigger;
	public Date timeStamp;

	/**
	 * notification constructor
	 * 
	 * @param description
	 *            describe what happened in the notification
	 * @param objectID
	 *            the id of the object
	 * @param objectType
	 *            the id that represent the model (comment or idea or topic
	 *            ...etc)
	 * @param notifictionTrigger
	 *            the user who trigger the notification
	 * @param notifiedUsers
	 *            the users who will be notified (NOTE: this notification is
	 *            added to each user)
	 * 
	 * @author Abdalla Abd-alhady
	 */
	public Notification(String description, long objectID, int objectType,
			User notifictionTrigger, List<User> notifiedUsers) {
		this.description = description;
		this.objectID = objectID;
		this.objectType = objectType;
		this.notifictionTrigger = notifictionTrigger;
		notified = notifiedUsers;
		timeStamp = new Date();
		for (User user : notifiedUsers) {
			user.notifications.add(this);
			user.save();
		}
	}

	public boolean cascadeDelete() {
		for (User user : this.notified) {
			user.notifications.remove(this);
			user.save();
		}
		this.delete();
		return true;
	}

	/**
	 * this method is for knowing which type this notification is created for.
	 * 
	 * @author Abdullah abd-alhady
	 * 
	 * @return the name of the type object
	 */
	public String getType() {
		String nameType = "";
		switch (objectType) {
		case 0:
			nameType = "ActionItem";
			break;
		case 1:
			nameType = "ActionLog";
			break;
		case 2:
			nameType = "Comment";
			break;
		case 3:
			nameType = "Entity";
			break;
		case 4:
			nameType = "Idea";
			break;
		case 5:
			nameType = "IdeaRating";
			break;
		case 6:
			nameType = "Organization";
			break;
		case 7:
			nameType = "permission";
			break;
		case 8:
			nameType = "Plan";
			break;
		case 9:
			nameType = "Role";
			break;
		case 10:
			nameType = "Tag";
			break;
		case 11:
			nameType = "topic";
			break;
		case 12:
			nameType = "User";
			break;
		case 13:
			nameType = "Merge Request";
			break;
		case 14:
			nameType = "Invitation";
			break;
		case 15:
			nameType = "Sharing";
			break;
		case 16:
			nameType = "deleting a topic";
			break;
		case 17:
			nameType = "hide idea";
			break;
		}
		return nameType;
	}

	/**
	 * this method is for the timing of the notification
	 * 
	 * @author Abdullah abd-alhady
	 * 
	 * @return the time left since the notification is created .
	 */
	public String getPeriod() {
		Date now = new Date();
		if (now.getYear() == timeStamp.getYear()) {
			if (now.getMonth() == timeStamp.getMonth()) {
				if (now.getDay() == timeStamp.getDay()) {
					if (now.getHours() == timeStamp.getHours()) {
						if (now.getMinutes() == timeStamp.getMinutes()) {
							return Math.abs(now.getSeconds()
									- timeStamp.getSeconds())
									+ " Second(s) ago";
						} else {
							return Math.abs(now.getMinutes()
									- timeStamp.getMinutes())
									+ " Minute(s) ago";
						}

					} else {
						return Math.abs(now.getHours() - timeStamp.getHours())
								+ " Hour(s) ago";
					}
				} else {
					return Math.abs(now.getDay() - timeStamp.getDay())
							+ " Day(s) ago";
				}
			} else {
				return Math.abs(now.getMonth() - timeStamp.getMonth())
						+ " Month(s) ago";
			}
		} else
			return Math.abs(now.getYear() - timeStamp.getYear())
					+ " Year(s) ago";
	}
}
